//
// Created by twetec on 25-7-3.
//

#ifndef NETWORK_PROBER_RPC_PERCEPTION_RPC_CALLER_INSTRUCTION_H
#define NETWORK_PROBER_RPC_PERCEPTION_RPC_CALLER_INSTRUCTION_H

#include "perception_rpc_client.pb.h"
#include "perception_rpc_client.grpc.pb.h"

#include "perception_rpc_caller.h"

namespace network_prober::rpc
{
/**
 * 一个reactor只能针对一个rpc方法
 */
class InstructionCallerRPCClientReactor final : public grpc::ClientBidiReactor<network_perception::rpc::InstructionRequest, network_perception::rpc::InstructionResponse>
{
public:
    network_perception::rpc::InstructionRequest instructionRequest{};
    network_perception::rpc::InstructionResponse instructionResponse{};

public:
    /**
     * 开始调用
     */
    void startCalling();

    /**
     * 等待连接结束
     */
    grpc::Status awaitCallingDone();

    InstructionCallerRPCClientReactor(network_perception::rpc::NetworkPerceptionServer::Stub* RPCClientStubPtr);

private:
    /**
     * 当一次写入完成时调用
     * @param ok 写入是否成功执行
     */
    void OnWriteDone(bool ok) override;
    /**
     * 当一次读取完成时调用
     * @param ok 读取是否成功执行
     */
    void OnReadDone(bool ok) override;
    /**
     * 响应RPC完成。我们将在 OnDone() 中执行最终清理
     */
    void OnDone(const grpc::Status& status) override;

private:
    std::mutex m_mutex;
    std::condition_variable m_condition;
    bool m_callingDone{false};
    grpc::Status m_callingStatus;
    grpc::ClientContext m_clientContext{};
};

class RecvInstruction;

class PerceptionRPCCallerInstruction final : public PerceptionRPCCaller<PerceptionRPCCallerInstruction>
{
public:
    /**
     * 调用实现
     */
    void callImpl();

    PerceptionRPCCallerInstruction();

private:
    /**
     * 处理 响应结果 指令
     */
    void _handleInstructionResponseResults(RecvInstruction&& instruction) const;

    /**
     * 处理 启用探针 指令
     */
    void _handleInstructionOpenProbe(RecvInstruction&& instruction) const;

    /**
     * 处理 停用探针 指令
     */
    void _handleInstructionCloseProbe(RecvInstruction&& instruction) const;

    /**
     * 处理 启用网口 指令
     */
    void _handleInstructionOpenNetwork(RecvInstruction&& instruction) const;

    /**
     * 处理 停用网口 指令
     */
    void _handleInstructionCloseNetwork(RecvInstruction&& instruction) const;

    /**
     * 探测观测目标 ICMP ipv4
     */
    void _handleInstructionICMPProbeDetectIPv4(RecvInstruction&& instruction) const;

    /**
     * 探测观测目标 ICMP ipv6
     */
    void _handleInstructionICMPProbeDetectIPv6(RecvInstruction&& instruction) const;

    /**
     * 探测观测目标 TCP ipv4
     */
    void _handleInstructionTCPProbeDetectIPv4(RecvInstruction&& instruction) const;

    /**
     * 探测观测目标 TCP ipv6
     */
    void _handleInstructionTCPProbeDetectIPv6(RecvInstruction&& instruction) const;

    /**
     * 探测观测目标 UDP ipv4
     */
    void _handleInstructionUDPProbeDetectIPv4(RecvInstruction&& instruction) const;

    /**
     *  探测观测目标 UDP ipv6
     */
    void _handleInstructionUDPProbeDetectIPv6(RecvInstruction&& instruction) const;

    /**
     * 納管观测设备
     */
    void _handleInstructionPipeManagementProbeTargets(RecvInstruction&& instruction) const;

    /**
     * 添加观测目标 ICMP ipv4
     */
    void _handleInstructionAddICMPProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 ICMP ipv6
     */
    void _handleInstructionAddICMPProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 TCP ipv4
     */
    void _handleInstructionAddTCPProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 TCP ipv6
     */
    void _handleInstructionAddTCPProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 UDP ipv4
     */
    void _handleInstructionAddUDPProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 UDP ipv6
     */
    void _handleInstructionAddUDPProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 HTTP ipv4
     */
    void _handleInstructionAddHTTPProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 HTTP ipv6
     */
    void _handleInstructionAddHTTPProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 HTTPS ipv4
     */
    void _handleInstructionAddHTTPSProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 HTTPS ipv6
     */
    void _handleInstructionAddHTTPSProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 MySQL ipv4
     */
    void _handleInstructionAddMySQLProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 MySQL ipv6
     */
    void _handleInstructionAddMySQLProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 PostgreSQL ipv4
     */
    void _handleInstructionAddPostgreSQLProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 PostgreSQL ipv6
     */
    void _handleInstructionAddPostgreSQLProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 SQLServer ipv4
     */
    void _handleInstructionAddSQLServerProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 SQLServer ipv6
     */
    void _handleInstructionAddSQLServerProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 MongoDB ipv4
     */
    void _handleInstructionAddMongoDBProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 MongoDB ipv6
     */
    void _handleInstructionAddMongoDBProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 Redis ipv4
     */
    void _handleInstructionAddRedisProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 添加观测目标 Redis ipv6
     */
    void _handleInstructionAddRedisProbeTargetIPv6(RecvInstruction &&instruction) const;

    /**
     * 更新观测目标 ICMP ipv4
     */
    void _handleInstructionUpdateICMPProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 ICMP ipv6
     */
    void _handleInstructionUpdateICMPProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 TCP ipv4
     */
    void _handleInstructionUpdateTCPProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 TCP ipv6
     */
    void _handleInstructionUpdateTCPProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
    * 更新观测目标 UDP ipv4
    */
    void _handleInstructionUpdateUDPProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 UDP ipv6
     */
    void _handleInstructionUpdateUDPProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
    * 更新观测目标 HTTP ipv4
    */
    void _handleInstructionUpdateHTTPProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 HTTP ipv6
     */
    void _handleInstructionUpdateHTTPProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
    * 更新观测目标 HTTPS ipv4
    */
    void _handleInstructionUpdateHTTPSProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 HTTPS ipv6
     */
    void _handleInstructionUpdateHTTPSProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 MySQL ipv4
     */
    void _handleInstructionUpdateMySQLProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 MySQL ipv6
     */
    void _handleInstructionUpdateMySQLProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 PostgreSQL ipv4
     */
    void _handleInstructionUpdatePostgreSQLProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 PostgreSQL ipv6
     */
    void _handleInstructionUpdatePostgreSQLProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 SQLServer ipv4
     */
    void _handleInstructionUpdateSQLServerProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 SQLServer ipv6
     */
    void _handleInstructionUpdateSQLServerProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 MongoDB ipv4
     */
    void _handleInstructionUpdateMongoDBProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 MongoDB ipv6
     */
    void _handleInstructionUpdateMongoDBProbeTargetIPv6(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 Redis ipv4
     */
    void _handleInstructionUpdateRedisProbeTargetIPv4(RecvInstruction &&instruction) const;
    /**
     * 更新观测目标 Redis ipv6
     */
    void _handleInstructionUpdateRedisProbeTargetIPv6(RecvInstruction &&instruction) const;

    /**
     * 删除观测目标
     */
    void _handleInstructionDeleteProbeTarget(RecvInstruction&& instruction) const;

    /**
     * 批量删除观测目标
     */
    void _handleInstructionBatchDeleteProbeTarget(RecvInstruction&& instruction) const;

    /**
     * 批量导入观测目标
     */
    void _handleInstructionBatchImportProbeTarget(RecvInstruction&& instruction) const;

    /**
     * 设备详情(趋势图)
     */
    void _handleInstructionDetailsProbeTarget(RecvInstruction&& instruction) const;

    /**
     * 开启观测设备
     */
    void _handleInstructionOpenProbeTarget(RecvInstruction&& instruction) const;

    /**
     * 开启观测设备
     */
    void _handleInstructionCloseProbeTarget(RecvInstruction&& instruction) const;

    /**
     * 时钟同步
     */
    void _handleInstructionTimeSynchronizaton(RecvInstruction&& instruction) const;

    /**
     * 测试TELNET_Ipv4备份目标
     */
    void _handleInstructionTestTELNETBackupTargetIPv4(RecvInstruction&& instruction) const;

    /**
     * 测试TELNET_Ipv4备份目标
     */
    void _handleInstructionTestTELNETBackupTargetIPv6(RecvInstruction&& instruction) const;

    /**
     * 添加TELNET_Ipv4备份目标
     */
    void _handleInstructionAddTELNETBackupTargetIPv4(RecvInstruction&& instruction) const;

    /**
     * 添加TELNET_Ipv6备份目标
     */
    void _handleInstructionAddTELNETBackupTargetIPv6(RecvInstruction&& instruction) const;

    /**
     * 修改TELNET_Ipv4备份目标
     */
    void _handleInstructionUpdateTELNETBackupTargetIPv4(RecvInstruction&& instruction) const;

    /**
     * 修改TELNET_Ipv6备份目标
     */
    void _handleInstructionUpdateTELNETBackupTargetIPv6(RecvInstruction&& instruction) const;

    /**
     * 测试SSH_Ipv4备份目标
     */
    void _handleInstructionTestSSHBackupTargetIPv4(RecvInstruction&& instruction) const;

    /**
     * 测试SSH_Ipv6备份目标
     */
    void _handleInstructionTestSSHBackupTargetIPv6(RecvInstruction&& instruction) const;

    /**
     * 添加SSH_Ipv4备份目标
     */
    void _handleInstructionAddSSHBackupTargetIPv4(RecvInstruction&& instruction) const;

    /**
     * 添加SSH_Ipv6备份目标
     */
    void _handleInstructionAddSSHBackupTargetIPv6(RecvInstruction&& instruction) const;

    /**
     * 修改SSH_Ipv4备份目标
     */
    void _handleInstructionUpdateSSHBackupTargetIPv4(RecvInstruction&& instruction) const;

    /**
     * 修改SSH_Ipv6备份目标
     */
    void _handleInstructionUpdateSSHBackupTargetIPv6(RecvInstruction&& instruction) const;

    /**
     * 删除备份目标
     */
    void _handleInstructionDeleteBackupTarget(RecvInstruction&& instruction) const;

    /**
     * 批量导入备份目标
     */
    void _handleInstructionBatchImportBackupTarget(RecvInstruction&& instruction) const;

private:
    std::unique_ptr<network_perception::rpc::NetworkPerceptionServer::Stub> m_RPCClientStubPtr{nullptr};
    std::unique_ptr<network_prober::rpc::InstructionCallerRPCClientReactor> m_RPCClientReactorPtr{nullptr};
};

}

#endif //NETWORK_PROBER_RPC_PERCEPTION_RPC_CALLER_INSTRUCTION_H
